package com.gylang.pdf;

import cn.hutool.core.util.StrUtil;
import com.openhtmltopdf.pdfboxout.PdfRendererBuilder;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.imgscalr.Scalr;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.function.Consumer;

/**
 * pdf渲染处理器
 *
 * @author gylang
 * data 2022/1/14
 */
public class PdfRenderProcessor {

    private PdfRenderConfiguration configuration;

    /**
     * 渲染pdf byte
     *
     * @param html   生成pdf的图片
     * @param config 特殊配置文件
     * @return 生成的pdf byte
     */
    public byte[] renderByte(String html, Consumer<PdfRendererBuilder>... config) {

        ByteArrayOutputStream actual = new ByteArrayOutputStream();
        PdfRendererBuilder builder = new PdfRendererBuilder();
        builder.withHtmlContent(html, configuration.getLocalResourcePath());
        builder.toStream(actual);
        addFont(builder, configuration.getFontPath());
        builder.useFastMode();
        for (Consumer<PdfRendererBuilder> conf : config) {
            conf.accept(builder);
        }
        try {
            builder.run();
        } catch (Exception e) {
            System.err.println("Failed to render resource (" + configuration.getLocalResourcePath() + ")");
            e.printStackTrace();
            return null;
        }

        return actual.toByteArray();

    }

    /**
     * 渲染document
     *
     * @param html   生成pdf的图片
     * @param config 特殊配置文件
     * @return 生成的pdf byte
     */
    public PDDocument renderDoc(String html, Consumer<PdfRendererBuilder>... config) throws IOException {
        byte[] bytes = renderByte(html, config);
        return PDDocument.load(bytes);

    }

    /**
     * 渲染 图片 pdf
     *
     * @param name      名称
     * @param html      html
     * @param page      页面
     * @param dpi       dpi
     * @param zoomRate  0-1
     * @param imageType 图片格式
     * @param config    特殊配置
     * @return
     * @throws IOException
     */
    public byte[] renderImg(String name, String html, int page, float dpi, float zoomRate, ImageType imageType,
                            Consumer<PdfRendererBuilder>... config) throws IOException {
        PDDocument pdDocument = renderDoc(html, config);
        PDFRenderer rendActual = new PDFRenderer(pdDocument);
        BufferedImage bi = rendActual.renderImageWithDPI(page, dpi, imageType);
        if (zoomRate > 0) {
            int width = bi.getWidth();
            int height = bi.getHeight();
            width = (int) (width * zoomRate);
            height = (int) (height * zoomRate);
            bi = Scalr.resize(bi, width, height);
        }
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(bi, StrUtil.subAfter(name, ".", true), outputStream);
        return outputStream.toByteArray();

    }

    /**
     * 添加字体库
     *
     * @param builder
     * @param dir
     */
    private static void addFont(PdfRendererBuilder builder, String dir) {
        File f = new File(dir);
        if (f.isDirectory()) {
            File[] files = f.listFiles((dir1, name) -> {
                String lower = name.toLowerCase();
                return lower.endsWith(".ttf") || lower.endsWith(".ttc");
            });
            for (File subFile : files) {
                String fontFamily = subFile.getName().substring(0, subFile.getName().lastIndexOf("."));
                builder.useFont(subFile, fontFamily);
            }
        }
    }

    public void setConfiguration(PdfRenderConfiguration configuration) {
        this.configuration = configuration;
    }
}
